using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
using WcfContrib.Resources;

namespace WcfContrib.Utils
{
	class Singleton<T>
	{
        static object syncLock = new object();

		private static readonly T instance;
		public static T Instance
		{
			get
            {
                lock (syncLock)
                {
                    return instance;
                }
            }
		}

        static Singleton()
        {
            lock (syncLock)
            {
                instance = CreateInstance();
            }
        }

        static T CreateInstance()
        {
            T result = default(T);

            ConstructorInfo ci = typeof(T).GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance, null, null, null);

            if (ci != null)
            {
                try
                {
                    result = (T)ci.Invoke(null);
                }
                catch (TargetInvocationException ex)
                {
                    throw new SingletonException(string.Format(ExceptionMessages.Singleton_InitFailure, typeof(T).Name), ex);
                }
            }
            else
            {
                throw new TargetException(string.Format(ExceptionMessages.Singleton_ConstructorMismatch, typeof(T).Name));
            }
            
            return result;
        }
	}
}